package com.zzedu.manager.impl;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.zzedu.common.enums.CommonEnums;
import com.zzedu.common.utils.SecurityUtils;
import com.zzedu.common.utils.bean.BeanUtils;
import com.zzedu.domain.*;
import com.zzedu.dto.ZzStudentLearnReportDTO;
import com.zzedu.enmuns.FileRelationTypeEnum;
import com.zzedu.framework.web.service.SysPasswordService;
import com.zzedu.manager.IZzStudentManager;
import com.zzedu.result.Result;
import com.zzedu.result.ResultEnum;
import com.zzedu.service.*;
import com.zzedu.stu.req.QueryPageReport;
import com.zzedu.stu.req.QueryReport;
import com.zzedu.stu.req.UpdatePwd;
import com.zzedu.stu.req.UpdateStudentInfo;
import com.zzedu.stu.rsp.ApiClzzVO;
import com.zzedu.stu.rsp.ApiZzStudentLearnReportInfoVO;
import com.zzedu.stu.rsp.ApiZzStudentLearnReportVO;
import com.zzedu.stu.rsp.ApiZzStudentVO;
import com.zzedu.utils.PageData;
import com.zzedu.vo.ZzStudentVO;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

@Component
public class ZzStudentManagerImpl implements IZzStudentManager {

    @Autowired
    IZzStudentService zzStudentService;

    @Autowired
    IZzUploadFileService zzUploadFileService;

    @Autowired
    IZzClassesService zzClassesService;

    @Autowired
    IZzStudentLearnReportService zzStudentLearnReportService;

    @Autowired
    IZzCourseService zzCourseService;

    @Autowired
    SysPasswordService passwordService;

    @Override
    public Result<ApiZzStudentVO> apiGetStudentInfo(Long id) {
        Result<ApiZzStudentVO> result = new Result<>();
        ZzStudent zzStudent = zzStudentService.getById(id);
        ApiZzStudentVO apiZzStudentVO = new ApiZzStudentVO();
        ZzStudentVO zzStudentVO = zzStudentService.convertVO(Lists.newArrayList(zzStudent)).get(0);
        BeanUtils.copyProperties(zzStudentVO, apiZzStudentVO);
        apiZzStudentVO.setExpireAt(zzStudent.getValidTo());
        //班级信息
        List<ZzClasses> zzClassesList = zzClassesService.getByZzClassesByStudentId(id);
        List<ApiClzzVO> apiClzzVOList = Optional.ofNullable(zzClassesList).orElse(Lists.newArrayList()).stream().map(zzClasses -> {
            ApiClzzVO apiClzzVO = new ApiClzzVO();
            BeanUtils.copyProperties(zzClasses, apiClzzVO);
            return apiClzzVO;
        }).collect(Collectors.toList());
        if(!CollectionUtils.isNotEmpty(apiClzzVOList)){
            List<ZzCourse> zzCourseList = this.zzCourseService.list(
                    Wrappers.lambdaQuery(ZzCourse.class)
                            .eq(ZzCourse::getState,CommonEnums.YES.getCode())
                            .apply("id in(select unit_id from zz_classes_send_student where deleted=0 and stu_id={0})",SecurityUtils.getUserId())
                            .orderByDesc(ZzCourse::getSortNo)
            );
            Set<String> sets = Sets.newLinkedHashSet();
            for(ZzCourse zzCourse:zzCourseList){
                sets.add(zzCourse.getLevel());
            }
            for(String level:sets){
                ApiClzzVO apiClzzVO = new ApiClzzVO();
                apiClzzVO.setLevel(level);
                apiClzzVOList.add(apiClzzVO);
            }
        }

        apiZzStudentVO.setApiClzzVOList(apiClzzVOList);

        apiZzStudentVO.setExpire(LocalDateTime.now().isAfter(zzStudent.getValidTo()));
        result.setData(apiZzStudentVO);
        result.setResultCode(ResultEnum.SUCCESS.getCode());
        result.setResultMessage(ResultEnum.SUCCESS.getDesc());
        return result;
    }

    @Override
    public Result apiUpdateInfo(UpdateStudentInfo data) {
        ZzStudent zzStudent = zzStudentService.getById(SecurityUtils.getUserId());
        if (null != data.getAvatar()) {
            //移除之前关联的附件
            zzUploadFileService.remove(Wrappers.lambdaQuery(ZzUploadFile.class)
                    .eq(ZzUploadFile::getRelationId, String.valueOf(zzStudent.getId()))
                    .eq(ZzUploadFile::getRelationType, FileRelationTypeEnum.STU_AVATAR.getCode())
                    .notIn(ZzUploadFile::getId, Lists.newArrayList(data.getAvatar())));
            zzUploadFileService.updateRelation(String.valueOf(zzStudent.getId()), Lists.newArrayList(data.getAvatar()));
        }
        zzStudent.setAvatar(data.getAvatar());
        zzStudent.setNickName(data.getNickName());
        zzStudentService.updateById(zzStudent);
        Result result = new Result();
        result.setResultCode(ResultEnum.SUCCESS.getCode());
        result.setResultMessage(ResultEnum.SUCCESS.getDesc());

        return result;
    }

    @Override
    public Result<PageData<ApiZzStudentLearnReportVO>> queryReport(QueryPageReport data) {
        ZzStudentLearnReportDTO zzStudentLearnReportDTO = new ZzStudentLearnReportDTO();
        zzStudentLearnReportDTO.setStuId(SecurityUtils.getUserId());
        zzStudentLearnReportDTO.setUnitId(data.getUnitId());
        zzStudentLearnReportDTO.setIsFinish(CommonEnums.YES.getCode());
        if (null != data.getReadFlag()) {
            zzStudentLearnReportDTO.setReadFlag(data.getReadFlag().getCode());
        }
        IPage<ZzStudentLearnReport> page = zzStudentLearnReportService.page(Page.of(data.getPageNum(), data.getPageSize()),
                zzStudentLearnReportService.buildQuery(zzStudentLearnReportDTO));
        PageData<ApiZzStudentLearnReportVO> pageData = new PageData<>();
        pageData.setTotal(page.getTotal());
        if (CollectionUtils.isNotEmpty(page.getRecords())) {
            List<ApiZzStudentLearnReportVO> apiZzStudentLearnReportVOList = Lists.newArrayList();
            for (ZzStudentLearnReport zzStudentLearnReport : page.getRecords()) {
                ZzCourse zzCourse = zzCourseService.getById(zzStudentLearnReport.getUnitId());
                ApiZzStudentLearnReportVO apiZzStudentLearnReportVO = new ApiZzStudentLearnReportVO();
                apiZzStudentLearnReportVO.setUnitId(zzCourse.getId());
                apiZzStudentLearnReportVO.setUnitName(zzCourse.getName());
                apiZzStudentLearnReportVO.setLevel(zzCourse.getLevel());
                apiZzStudentLearnReportVO.setId(zzStudentLearnReport.getId());
                apiZzStudentLearnReportVO.setGmtCreate(zzStudentLearnReport.getGmtCreate());
                apiZzStudentLearnReportVO.setReadFlag(CommonEnums.getCode(zzStudentLearnReport.getReadFlag()));
                apiZzStudentLearnReportVOList.add(apiZzStudentLearnReportVO);
            }
            pageData.setRowData(apiZzStudentLearnReportVOList);
        }
        Result<PageData<ApiZzStudentLearnReportVO>> result = new Result<>();
        result.setData(pageData);
        result.setResultCode(ResultEnum.SUCCESS.getCode());
        result.setResultMessage(ResultEnum.SUCCESS.getDesc());
        return result;
    }

    @Override
    public Result<ApiZzStudentLearnReportInfoVO> queryReportInfo(QueryReport data) {
        ZzStudentLearnReport zzStudentLearnReport = zzStudentLearnReportService.getOne(Wrappers.lambdaQuery(ZzStudentLearnReport.class)
                .eq(ZzStudentLearnReport::getId, data.getId())
                .eq(ZzStudentLearnReport::getStuId, SecurityUtils.getUserId())
        );
        LambdaUpdateWrapper<ZzStudentLearnReport> learnReportLambdaUpdateWrapper = Wrappers.lambdaUpdate(ZzStudentLearnReport.class);
        learnReportLambdaUpdateWrapper.eq(ZzStudentLearnReport::getId, data.getId());
        learnReportLambdaUpdateWrapper.set(ZzStudentLearnReport::getReadFlag, CommonEnums.YES.getCode());
        learnReportLambdaUpdateWrapper.set(ZzStudentLearnReport::getGmtModify, LocalDateTime.now());
        learnReportLambdaUpdateWrapper.setIncrBy(ZzStudentLearnReport::getReadCount, 1);
        this.zzStudentLearnReportService.update(learnReportLambdaUpdateWrapper);
        ZzCourse zzCourse = zzCourseService.getById(zzStudentLearnReport.getUnitId());
        ApiZzStudentLearnReportInfoVO apiZzStudentLearnReportInfoVO = new ApiZzStudentLearnReportInfoVO();
        apiZzStudentLearnReportInfoVO.setUnitId(zzCourse.getId());
        apiZzStudentLearnReportInfoVO.setUnitName(zzCourse.getName());
        apiZzStudentLearnReportInfoVO.setLevel(zzCourse.getLevel());
        apiZzStudentLearnReportInfoVO.setId(zzStudentLearnReport.getId());
        apiZzStudentLearnReportInfoVO.setReadFlag(CommonEnums.getCode(zzStudentLearnReport.getReadFlag()));
        apiZzStudentLearnReportInfoVO.setReportData(JSON.parseObject(zzStudentLearnReport.getContent()));
        Result<ApiZzStudentLearnReportInfoVO> result = new Result<>();
        result.setResultCode(ResultEnum.SUCCESS.getCode());
        result.setResultMessage(ResultEnum.SUCCESS.getDesc());
        result.setData(apiZzStudentLearnReportInfoVO);
        return result;
    }

    /**
     * 修改密码
     * @param data
     * @return
     */
    @Override
    public Result updatePwd(UpdatePwd data) {
        Result result = new Result<>();
        if (!data.getConfirmPassWord().equals(data.getPassWord())) {
            result.setResultCode(ResultEnum.FAIL.getCode());
            result.setResultMessage("密码确认密码不匹配");
            return result;
        }
        ZzStudent zzStudent = zzStudentService.getById(SecurityUtils.getUserId());
        if (!SecurityUtils.matchesPassword(data.getOldPassWord(), zzStudent.getPwd())) {
            result.setResultCode(ResultEnum.FAIL.getCode());
            result.setResultMessage("原始密码不匹配");
            return result;
        }
        zzStudent.setPwd(passwordService.encryptPassword(data.getPassWord()));
        this.zzStudentService.updateById(zzStudent);
        result.setResultCode(ResultEnum.SUCCESS.getCode());
        result.setResultMessage(ResultEnum.SUCCESS.getDesc());
        return result;
    }
}
